<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>vue的响应式</title>
</head>

<body>
  <div id="app">
    <h2>{{ message }}</h2>
    <h2>{{ message }}</h2>
    <h2>{{ message }}</h2>
  </div>

  <script src="../../js/vue.js"></script>
  <script>
    const app = new Vue({
      // el: '#app',
      data: {
        message: "你好呀",
        name: "Mr.chen",
      }
    }).$mount('#app');

    // 使用Object.defineProperty() 监听数据改变与获取
    const obj = {
      message: "你好呀",
      name: "Mr.chen",
    }

    // 解析对象 进行监听
    // 1. 将对象中的所有属性[key]放到一个数组中, 进行遍历
    Object.keys(obj).forEach(key => {
      // value: obj对象中的每一个值
      let value = obj[key];
      Object.defineProperty(obj, key, {
        // set: 监听到数据改变时触发
        set(newValue) {
          console.log("[属性改变] value >>>", value, "new >>>", newValue);
          value = newValue;
          // dep.notify();
        },
        // get: 监听数据获取
        get() {
          console.log("[属性获取] value >>>", value);
          return value;
        }
      })
    })


    // 发布者订阅者模式
    // 1. 发布者
    class Dependency {
      constructor() {
        this.subscribes = []
      }

      // 添加订阅者对象
      addSub(watcher) {
        this.subscribes.push(watcher);
      }

      // 通知改变方法
      notify() {
        this.subscribes.forEach(item => {
          // 监听到改变后调用notify 通知所有订阅者 让他们自己更新
          item.update();
        })
        return "通知已完成";
      }
    }

    // 2. 订阅者
    class Watcher {
      constructor(name) {
        this.name = name;
      }

      // 更新方法
      update() {
        console.log(this.name, ">>> 发生update更新");
      }
    }


    // 3. 创建一个发布者
    const dep = new Dependency();

    // 4. 创建三个订阅者 将三个订阅者全部添加
    const w1 = new Watcher('Mr.1');
    const w2 = new Watcher('Mr.2');
    const w3 = new Watcher('Mr.3');

    dep.addSub(w1);
    dep.addSub(w2);
    dep.addSub(w3);

    // 5. 通知各个订阅者 让他们改变
    dep.notify();

  </script>
</body>

</html>